package com.wfy.common.util;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheManager;

import java.io.Serializable;

/**
 * Created with IntelliJ IDEA.
 * User: wangxindong
 * Date: 2017/9/29
 * Time: 16:24
 */
public class CacheUtils {

    // ================================================================
    // Constants
    // ================================================================

    private static final String DEFAULT_SYS_CACHE = "springbpptSysCache";
    private static final Logger LOGGER = LoggerFactory.getLogger(CacheUtils.class);


    // ================================================================
    // Fields
    // ================================================================

    private static CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);

    /**
     *
     */
    private static boolean SERIALIZE_ABLE = false;


    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    public static Object get(String key) {
        return get(DEFAULT_SYS_CACHE, key);
    }

    public static void put(String key, Object value) {
        put(DEFAULT_SYS_CACHE, key, value);
    }


    public static void remove(String key) {
        remove(DEFAULT_SYS_CACHE, key);
    }


    public static Object get(String cacheName, String key) {
        Cache.ValueWrapper element = getCache(cacheName).get(key);
        if (element != null) {
            Object value = element.get();
            if (value != null && SERIALIZE_ABLE) {
                return SerializeUtils.deserializeFromString(value.toString());
            } else {
                return value;
            }
        }
        return null;
    }


    public static void put(String cacheName, String key, Object value) {
        if (SERIALIZE_ABLE && value != null) {
            getCache(cacheName).put(key, SerializeUtils.serializeToString((Serializable) value));
        } else {
            getCache(cacheName).put(key, value);
        }
    }


    public static void remove(String cacheName, String key) {
        // 从缓存中移除key对应的缓存
        getCache(cacheName).evict(key);
    }

    public static CacheManager getCacheManager() {
        return cacheManager;
    }


    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    private static Cache getCache(String cacheName) {
        // 防止cache不为空,不设置序列化
        if (cacheManager instanceof RedisCacheManager) {
            SERIALIZE_ABLE = true;
        }
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            if (cacheManager instanceof RedisCacheManager) {
                RedisCacheManager manager = (RedisCacheManager) cacheManager;
                manager.setCacheNames(Lists.newArrayList(cacheName));
                SERIALIZE_ABLE = true;
            }
            cache = cacheManager.getCache(cacheName);
        }
        return cache;
    }

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
